package whf.framework.workflow.assign;

import java.io.ByteArrayInputStream;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.jbpm.graph.exe.ExecutionContext;
import org.jbpm.taskmgmt.def.AssignmentHandler;
import org.jbpm.taskmgmt.exe.Assignable;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

import whf.framework.exception.AppException;
import whf.framework.workflow.assign.parser.AssignmentParser;
import whf.framework.workflow.assign.parser.AssignmentParserFactory;

/**
 * 基于xml的解析 xml格式：参考assign.xsd
 * @author king
 *
 */
@SuppressWarnings(value={"serial","unchecked"})
public class XmlAssignmentHandler implements AssignmentHandler {
	protected String expression;
	
	private Collection<String> users = new HashSet<String>();
	
	private Set<AssignmentParser> parsers = new HashSet<AssignmentParser>();
	
	public void assign(Assignable assignable, ExecutionContext executionContext) throws Exception {
		//
		executionContext.getTask().getSwimlane().getPooledActorsExpression();
		//
		String xml = "<assign>" + expression +"</assign>";
		SAXBuilder builder = new SAXBuilder();
		ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes());
		Document doc = builder.build(bis);
		List<Element> children = doc.getRootElement().getChildren();
		for(Element ele : children){
			AssignmentParser parser = AssignmentParserFactory.getAssignmentParser(ele, null, null);
			this.addAllParsersAndUsers(parser);
		}
		//
		if(users.isEmpty()) {
			throw new Exception("Can not found any users:\n" + xml);
		}
		String actorIds[] = new String[users.size()];
		int index = 0;
		for(Iterator<String> it = users.iterator(); it.hasNext(); ) {
			String username = it.next();
			actorIds[index] = username;
			index ++;
		}
		if(actorIds.length == 1) {
			assignable.setActorId(actorIds[0]);
		} else {
			assignable.setPooledActors(actorIds);
		}
	}
	
	private void addAllParsersAndUsers(AssignmentParser parser) throws AppException{
		if(parser == null) return;
		this.parsers.add(parser);
		Collection<String> users = parser.getUsers();
		if(users != null) 
			this.users.addAll(users);
		Set<AssignmentParser> childrenParsers = parser.getChildrenParsers();
		if(childrenParsers != null && !childrenParsers.isEmpty()) {
			for(AssignmentParser p: childrenParsers) {
				this.addAllParsersAndUsers(p);
			}
		}
	}
}
